﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace T.FAS.Runtime.ScheduleJob.SPI
{
    /// <summary>
    /// A hash based set.
    /// </summary>
    [Serializable]
    public class HashSet : ArrayList, ISet
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="HashSet"/> class.
        /// </summary>
        public HashSet()
            : base()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="HashSet"/> class.
        /// </summary>
        /// <param name="c">The <see cref="T:System.Collections.ICollection"/> whose elements are copied to the new list.</param>
        /// <exception cref="T:System.ArgumentNullException">
        /// 	<paramref name="c"/> is <see langword="null"/>.</exception>
        public HashSet(ICollection c)
        {
            AddAll(c);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="HashSet"/> class.
        /// </summary>
        /// <param name="capacity">The capacity.</param>
        public HashSet(int capacity)
            : base(capacity)
        {
        }

        /// <summary>
        /// Unmodifiables the hash set.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <returns></returns>
        public static HashSet UnmodifiableHashSet(ICollection collection)
        {
            ArrayList items = new ArrayList(collection);
            items = ArrayList.ReadOnly(items);
            return new HashSet(items);
        }

        /// <summary>
        /// Adds a new element to the ArrayList if it is not already present.
        /// </summary>		
        /// <param name="obj">Element to insert to the ArrayList.</param>
        /// <returns>Returns true if the new element was inserted, false otherwise.</returns>
        public new virtual bool Add(object obj)
        {
            bool inserted;

            if ((inserted = Contains(obj)) == false)
            {
                base.Add(obj);
            }

            return !inserted;
        }

        /// <summary>
        /// Adds all the elements of the specified collection that are not present to the list.
        /// </summary>
        /// <param name="c">Collection where the new elements will be added</param>
        /// <returns>Returns true if at least one element was added, false otherwise.</returns>
        public bool AddAll(ICollection c)
        {
            IEnumerator e = new ArrayList(c).GetEnumerator();
            bool added = false;

            while (e.MoveNext() == true)
            {
                if (Add(e.Current) == true)
                {
                    added = true;
                }
            }

            return added;
        }

        /// <summary>
        /// Returns the first item in the set.
        /// </summary>
        /// <returns>First object.</returns>
        public object First()
        {
            return this[0];
        }

        /// <summary>
        /// Returns a copy of the HashSet instance.
        /// </summary>		
        /// <returns>Returns a shallow copy of the current HashSet.</returns>
        public override object Clone()
        {
            return MemberwiseClone();
        }
    }
}
